package com.example.onlineanswer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.onlineanswer.mapper.QuestionMapper;
import com.example.onlineanswer.mapper.QuestionOptionMapper;
import com.example.onlineanswer.mapper.QuestionTypeMapper;
import com.example.onlineanswer.model.dto.QuestionDTO;
import com.example.onlineanswer.model.entity.Question;
import com.example.onlineanswer.model.entity.QuestionOption;
import com.example.onlineanswer.model.entity.QuestionType;
import com.example.onlineanswer.model.vo.QuestionVO;
import com.example.onlineanswer.service.QuestionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 题目服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    private final QuestionMapper questionMapper;
    private final QuestionTypeMapper questionTypeMapper;
    private final QuestionOptionMapper questionOptionMapper;

    @Override
    public IPage<QuestionVO> pageQuestionList(Page<QuestionVO> page, Long contestId, String contestTitle, Integer typeId, Integer difficulty, Integer status, String keyword) {
        return questionMapper.pageQuestionList(page, contestId, contestTitle, typeId, difficulty, status, keyword);
    }

    @Override
    public QuestionVO getQuestionDetailById(Long id) {
        QuestionVO questionVO = questionMapper.getQuestionDetailById(id);
        if (questionVO != null && (questionVO.getTypeId() == 1 || questionVO.getTypeId() == 2)) {
            // 如果是选择题，加载选项
            List<QuestionOption> options = questionOptionMapper.getOptionsByQuestionId(id);
            questionVO.setOptions(options);
        }
        return questionVO;
    }

    @Override
    public QuestionVO getQuestionDetail(Long id) {
        // 复用已实现的方法
        return getQuestionDetailById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createQuestion(Question question) {
        // 设置初始值
        question.setCreateTime(LocalDateTime.now());
        question.setUpdateTime(LocalDateTime.now());
        
        // 设置排序号（如果未设置）
        if (question.getOrderNum() == null) {
            // 获取当前最大排序号
            int count = getQuestionCountByContestId(question.getContestId());
            question.setOrderNum(count + 1);
        }
        
        // 设置状态（如果未设置）
        if (question.getStatus() == null) {
            question.setStatus(0); // 默认为待审核
        }
        
        baseMapper.insert(question);
        
        // 处理选项（针对选择题）
        if ((question.getTypeId() == 1 || question.getTypeId() == 2) && question.getOptions() != null) {
            for (QuestionOption option : question.getOptions()) {
                option.setQuestionId(question.getId());
                option.setCreateTime(LocalDateTime.now());
                option.setUpdateTime(LocalDateTime.now());
                questionOptionMapper.insert(option);
            }
        }
        
        return question.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuestion(Long id, Question question) {
        Question dbQuestion = getById(id);
        if (dbQuestion == null) {
            return false;
        }
        
        question.setId(id);
        question.setUpdateTime(LocalDateTime.now());
        
        // 更新题目基本信息
        boolean success = baseMapper.updateById(question) > 0;
        
        // 处理选项（针对选择题）
        if (success && (question.getTypeId() == 1 || question.getTypeId() == 2) && question.getOptions() != null) {
            // 删除旧选项
            LambdaQueryWrapper<QuestionOption> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(QuestionOption::getQuestionId, id);
            questionOptionMapper.delete(wrapper);
            
            // 添加新选项
            for (QuestionOption option : question.getOptions()) {
                option.setQuestionId(id);
                option.setCreateTime(LocalDateTime.now());
                option.setUpdateTime(LocalDateTime.now());
                questionOptionMapper.insert(option);
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuestion(Long id) {
        // 删除选项
        LambdaQueryWrapper<QuestionOption> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QuestionOption::getQuestionId, id);
        questionOptionMapper.delete(wrapper);
        
        // 删除题目
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public List<QuestionType> getAllQuestionTypes() {
        return questionTypeMapper.getAllQuestionTypes();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchImportQuestions(Long contestId, List<Question> questions) {
        if (questions == null || questions.isEmpty()) {
            return 0;
        }
        
        // 获取当前最大排序号
        int startOrderNum = getQuestionCountByContestId(contestId) + 1;
        int successCount = 0;
        
        for (int i = 0; i < questions.size(); i++) {
            try {
                Question question = questions.get(i);
                question.setContestId(contestId);
                question.setOrderNum(startOrderNum + i);
                question.setStatus(0); // 默认为待审核
                question.setCreateTime(LocalDateTime.now());
                question.setUpdateTime(LocalDateTime.now());
                
                baseMapper.insert(question);
                
                // 处理选项（针对选择题）
                if ((question.getTypeId() == 1 || question.getTypeId() == 2) && question.getOptions() != null) {
                    for (QuestionOption option : question.getOptions()) {
                        option.setQuestionId(question.getId());
                        option.setCreateTime(LocalDateTime.now());
                        option.setUpdateTime(LocalDateTime.now());
                        questionOptionMapper.insert(option);
                    }
                }
                
                successCount++;
            } catch (Exception e) {
                log.error("导入题目失败: {}", e.getMessage(), e);
            }
        }
        
        return successCount;
    }

    @Override
    public List<Question> getQuestionsByContestId(Long contestId) {
        return questionMapper.getQuestionsByContestId(contestId);
    }

    @Override
    public Long getNextQuestionId(Long contestId, Integer currentOrderNum) {
        return questionMapper.getNextQuestionId(contestId, currentOrderNum);
    }

    @Override
    public int getQuestionCountByContestId(Long contestId) {
        return questionMapper.getQuestionCountByContestId(contestId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reviewQuestion(Long id, Integer status, Long reviewerId) {
        Question question = getById(id);
        if (question == null) {
            return false;
        }
        
        // 只有待审核状态的题目才能被审核
        if (question.getStatus() != 0) {
            return false;
        }
        
        // 设置审核状态（不保存审核人ID，因为数据库中没有该字段）
        question.setStatus(status);
        question.setUpdateTime(LocalDateTime.now());
        
        // 记录审核信息到日志
        log.info("题目 {} 被用户 {} 审核为 {}", id, reviewerId, status == 1 ? "通过" : "拒绝");
        
        return updateById(question);
    }

    @Override
    public QuestionDTO getQuestionDetails(Long questionId) {
        Question question = this.getById(questionId);
        if (question == null) {
            return null;
        }
        
        QuestionDTO questionDTO = new QuestionDTO();
        BeanUtils.copyProperties(question, questionDTO);
        
        // 获取题目类型名称
        if (question.getTypeId() != null) {
            QuestionType questionType = questionTypeMapper.selectById(question.getTypeId());
            if (questionType != null) {
                questionDTO.setTypeName(questionType.getTypeName());
            }
        }
        
        // 设置当前题目号和总题目数
        questionDTO.setCurrentNumber(question.getOrderNum());
        int totalQuestions = getQuestionCountByContestId(question.getContestId());
        questionDTO.setTotalQuestions(totalQuestions);
        
        // 获取选项
        if (question.getTypeId() == 1 || question.getTypeId() == 2) { // 单选或多选题
            List<QuestionOption> options = questionOptionMapper.getOptionsByQuestionId(questionId);
            questionDTO.setOptions(options);
        }
        
        return questionDTO;
    }

    @Override
    public boolean checkAnswer(Long questionId, String answer) {
        Question question = this.getById(questionId);
        if (question == null) {
            log.error("题目不存在: {}", questionId);
            return false;
        }
        
        log.info("校验答案 - 题目ID: {}, 题目类型: {}, 用户答案: {}", 
                questionId, question.getTypeId(), answer);
        
        // 获取正确答案
        String correctAnswer = "";
        
        if (question.getTypeId() == 1 || question.getTypeId() == 2) { // 单选或多选题
            List<QuestionOption> options = questionOptionMapper.getOptionsByQuestionId(questionId);
            log.debug("获取到选项数量: {}", options != null ? options.size() : 0);
            
            // 调试信息：输出所有选项及其正确性
            if (options != null && !options.isEmpty()) {
                for (QuestionOption option : options) {
                    log.debug("选项信息 - ID: {}, 序号: {}, 内容: {}, 是否正确: {}", 
                            option.getId(), option.getOptionOrder(), 
                            option.getOptionContent(), option.getCorrect());
                }
            } else {
                log.warn("题目 {} 没有选项", questionId);
            }
            
            if (question.getTypeId() == 1) { // 单选题
                for (QuestionOption option : options) {
                    if (option.getCorrect() != null && option.getCorrect()) {
                        correctAnswer = option.getOptionOrder();
                        log.debug("单选题正确答案: {}", correctAnswer);
                        break;
                    }
                }
            } else { // 多选题
                List<String> correctOptions = new ArrayList<>();
                for (QuestionOption option : options) {
                    if (option.getCorrect() != null && option.getCorrect()) {
                        correctOptions.add(option.getOptionOrder());
                    }
                }
                // 按字母顺序排序正确选项
                Collections.sort(correctOptions);
                correctAnswer = String.join(",", correctOptions);
                log.debug("多选题正确答案: {}", correctAnswer);
            }
        } else if (question.getTypeId() == 3) { // 判断题
            // 判断题的参考答案可能为null，提供默认值
            correctAnswer = question.getReferAnswer() != null ? question.getReferAnswer() : "";
            log.debug("判断题正确答案: {}", correctAnswer);
        } else if (question.getTypeId() == 4 || question.getTypeId() == 5) { // 填空题或简答题
            // 填空题和简答题的参考答案可能为null，提供默认值
            correctAnswer = question.getReferAnswer() != null ? question.getReferAnswer() : "";
            log.debug("填空/简答题正确答案: {}", correctAnswer);
        }
        
        // 处理用户答案为null的情况
        String processedUserAnswer = answer != null ? answer : "";
        
        // 检查答案是否正确
        boolean isCorrect = false;
        
        if (question.getTypeId() == 1) { // 单选题
            // 单选题忽略大小写比较
            isCorrect = correctAnswer.equalsIgnoreCase(processedUserAnswer.trim());
        } else if (question.getTypeId() == 2) { // 多选题需要特殊处理
            // 将用户答案按字母顺序排序后比较
            if (!processedUserAnswer.isEmpty()) {
                String[] answerParts = processedUserAnswer.split(",");
                Arrays.sort(answerParts);
                processedUserAnswer = String.join(",", answerParts);
                isCorrect = correctAnswer.equalsIgnoreCase(processedUserAnswer);
            }
        } else if (question.getTypeId() == 3) { // 判断题也忽略大小写
            isCorrect = correctAnswer.equalsIgnoreCase(processedUserAnswer.trim());
        } else if (question.getTypeId() == 4 || question.getTypeId() == 5) { // 填空题或简答题
            // 简单判断，可以根据需要实现更复杂的匹配逻辑
            String processedCorrectAnswer = correctAnswer.trim().toLowerCase();
            processedUserAnswer = processedUserAnswer.trim().toLowerCase();
            isCorrect = processedCorrectAnswer.equals(processedUserAnswer);
        }
        
        log.info("答案校验结果 - 题目ID: {}, 用户答案: {}, 正确答案: {}, 是否正确: {}", 
                questionId, processedUserAnswer, correctAnswer, isCorrect);
        
        return isCorrect;
    }

    @Override
    public Question getNextQuestion(Long contestId, Long currentQuestionId) {
        Question currentQuestion = this.getById(currentQuestionId);
        if (currentQuestion == null) {
            return null;
        }
        
        // 查询当前题目的排序号
        Integer currentOrderNum = currentQuestion.getOrderNum();
        
        // 查询下一题
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Question::getContestId, contestId)
                   .eq(Question::getStatus, 1) // 已通过审核的题目
                   .gt(Question::getOrderNum, currentOrderNum)
                   .orderByAsc(Question::getOrderNum)
                   .last("LIMIT 1");
        
        return this.getOne(queryWrapper);
    }

    /**
     * 分页查询竞赛的题目
     */
    @Override
    public IPage<Question> getQuestionsByContestId(Page<Question> page, Long contestId) {
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Question::getContestId, contestId)
                   .orderByAsc(Question::getOrderNum);
        return baseMapper.selectPage(page, queryWrapper);
    }

    /**
     * 更新题目
     */
    @Override
    public boolean updateQuestion(Question question) {
        question.setUpdateTime(LocalDateTime.now());
        return updateById(question);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int importQuestionsFromExcel(Long contestId, MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        Workbook workbook = new XSSFWorkbook(inputStream);
        Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
        
        int startOrderNum = getQuestionCountByContestId(contestId) + 1;
        int successCount = 0;
        
        // 跳过标题行，从第二行开始读取
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) continue;
            
            try {
                // 解析Excel行数据
                Question question = parseQuestionFromExcelRow(row);
                if (question == null) continue;
                
                // 设置题目属性
                question.setContestId(contestId);
                question.setOrderNum(startOrderNum + successCount);
                question.setStatus(0); // 默认为待审核
                question.setCreateTime(LocalDateTime.now());
                question.setUpdateTime(LocalDateTime.now());
                
                // 保存题目
                baseMapper.insert(question);
                
                // 处理选项（针对选择题）
                if ((question.getTypeId() == 1 || question.getTypeId() == 2) && question.getOptions() != null) {
                    for (QuestionOption option : question.getOptions()) {
                        option.setQuestionId(question.getId());
                        option.setCreateTime(LocalDateTime.now());
                        option.setUpdateTime(LocalDateTime.now());
                        questionOptionMapper.insert(option);
                    }
                }
                
                successCount++;
            } catch (Exception e) {
                log.error("导入第{}行题目失败: {}", i + 1, e.getMessage(), e);
            }
        }
        
        workbook.close();
        inputStream.close();
        
        return successCount;
    }
    
    /**
     * 从Excel行解析题目数据
     *
     * @param row Excel行
     * @return 题目对象
     */
    private Question parseQuestionFromExcelRow(Row row) {
        try {
            Question question = new Question();
            
            // 读取基本数据
            int typeId = (int) row.getCell(0).getNumericCellValue(); // 题目类型
            String content = row.getCell(1).getStringCellValue(); // 题目内容
            int difficulty = (int) row.getCell(2).getNumericCellValue(); // 难度
            int score = (int) row.getCell(3).getNumericCellValue(); // 分数
            int timeLimit = (int) row.getCell(4).getNumericCellValue(); // 时间限制
            String answer = row.getCell(5).getStringCellValue(); // 答案（根据题型不同，可能是选项序号、是非或文本）
            
            // 设置题目属性
            question.setTypeId(Long.valueOf(typeId));
            question.setContent(content);
            question.setDifficulty(difficulty);
            question.setScore(score);
            question.setTimeLimit(timeLimit);
            
            // 判断题特殊处理
            if (typeId == 3) { // 判断题
                // 假设answer字段中"1"表示正确，"0"表示错误
                question.setCorrectAnswer("1".equals(answer) || "true".equalsIgnoreCase(answer));
            }
            
            // 处理选项（针对选择题）
            if (typeId == 1 || typeId == 2) { // 单选或多选题
                List<QuestionOption> options = new ArrayList<>();
                
                // 读取选项，假设选项从第7列开始，每两列一组(选项内容和是否正确)
                for (int i = 6; i < row.getLastCellNum(); i += 2) {
                    Cell optionCell = row.getCell(i);
                    Cell isCorrectCell = row.getCell(i + 1);
                    
                    if (optionCell == null || isCorrectCell == null) break;
                    
                    String optionContent = optionCell.getStringCellValue();
                    boolean isCorrect = isCorrectCell.getBooleanCellValue();
                    
                    if (StringUtils.hasText(optionContent)) {
                        QuestionOption option = new QuestionOption();
                        option.setOptionContent(optionContent);
                        option.setCorrect(isCorrect);
                        option.setOptionOrder(String.valueOf((char)('A' + (i - 6) / 2)));  // 设置选项顺序为A, B, C...
                        options.add(option);
                    }
                }
                
                question.setOptions(options);
            } else if (typeId == 4 || typeId == 5) { // 填空题或简答题
                question.setReferAnswer(answer);
            }
            
            return question;
        } catch (Exception e) {
            log.error("解析题目行失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public Resource generateQuestionImportTemplate() throws IOException {
        // 创建工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("题目导入模板");
        
        // 创建标题行样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);
        headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        
        // 创建标题行
        Row headerRow = sheet.createRow(0);
        String[] headers = {
            "题目类型(1单选2多选3判断4填空5简答)", 
            "题目内容", 
            "难度(1简单2中等3困难)", 
            "分值", 
            "时间限制(秒)", 
            "标准答案",
            "选项A内容", "选项A是否正确", 
            "选项B内容", "选项B是否正确", 
            "选项C内容", "选项C是否正确", 
            "选项D内容", "选项D是否正确"
        };
        
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
            sheet.setColumnWidth(i, 256 * 20); // 设置列宽
        }
        
        // 创建示例数据行
        // 示例1：单选题
        Row singleChoiceRow = sheet.createRow(1);
        singleChoiceRow.createCell(0).setCellValue(1); // 题目类型：单选题
        singleChoiceRow.createCell(1).setCellValue("以下哪个是Java的基本数据类型？"); // 题目内容
        singleChoiceRow.createCell(2).setCellValue(1); // 难度：简单
        singleChoiceRow.createCell(3).setCellValue(10); // 分值
        singleChoiceRow.createCell(4).setCellValue(60); // 时间限制
        singleChoiceRow.createCell(5).setCellValue("A"); // 标准答案
        // 选项
        singleChoiceRow.createCell(6).setCellValue("int"); // 选项A内容
        singleChoiceRow.createCell(7).setCellValue(true); // 选项A是否正确
        singleChoiceRow.createCell(8).setCellValue("String"); // 选项B内容
        singleChoiceRow.createCell(9).setCellValue(false); // 选项B是否正确
        singleChoiceRow.createCell(10).setCellValue("ArrayList"); // 选项C内容
        singleChoiceRow.createCell(11).setCellValue(false); // 选项C是否正确
        singleChoiceRow.createCell(12).setCellValue("Object"); // 选项D内容
        singleChoiceRow.createCell(13).setCellValue(false); // 选项D是否正确
        
        // 示例2：多选题
        Row multiChoiceRow = sheet.createRow(2);
        multiChoiceRow.createCell(0).setCellValue(2); // 题目类型：多选题
        multiChoiceRow.createCell(1).setCellValue("以下哪些是Java集合框架的接口？"); // 题目内容
        multiChoiceRow.createCell(2).setCellValue(2); // 难度：中等
        multiChoiceRow.createCell(3).setCellValue(15); // 分值
        multiChoiceRow.createCell(4).setCellValue(90); // 时间限制
        multiChoiceRow.createCell(5).setCellValue("A,B,D"); // 标准答案
        // 选项
        multiChoiceRow.createCell(6).setCellValue("List"); // 选项A内容
        multiChoiceRow.createCell(7).setCellValue(true); // 选项A是否正确
        multiChoiceRow.createCell(8).setCellValue("Set"); // 选项B内容
        multiChoiceRow.createCell(9).setCellValue(true); // 选项B是否正确
        multiChoiceRow.createCell(10).setCellValue("HashTable"); // 选项C内容
        multiChoiceRow.createCell(11).setCellValue(false); // 选项C是否正确
        multiChoiceRow.createCell(12).setCellValue("Map"); // 选项D内容
        multiChoiceRow.createCell(13).setCellValue(true); // 选项D是否正确
        
        // 示例3：判断题
        Row judgmentRow = sheet.createRow(3);
        judgmentRow.createCell(0).setCellValue(3); // 题目类型：判断题
        judgmentRow.createCell(1).setCellValue("Java是一种解释型语言。"); // 题目内容
        judgmentRow.createCell(2).setCellValue(1); // 难度：简单
        judgmentRow.createCell(3).setCellValue(5); // 分值
        judgmentRow.createCell(4).setCellValue(30); // 时间限制
        judgmentRow.createCell(5).setCellValue("1"); // 标准答案 (1表示正确，0表示错误)
        
        // 示例4：填空题
        Row fillBlankRow = sheet.createRow(4);
        fillBlankRow.createCell(0).setCellValue(4); // 题目类型：填空题
        fillBlankRow.createCell(1).setCellValue("Java中用于定义常量的关键字是____。"); // 题目内容
        fillBlankRow.createCell(2).setCellValue(1); // 难度：简单
        fillBlankRow.createCell(3).setCellValue(8); // 分值
        fillBlankRow.createCell(4).setCellValue(60); // 时间限制
        fillBlankRow.createCell(5).setCellValue("final"); // 标准答案
        
        // 示例5：简答题
        Row shortAnswerRow = sheet.createRow(5);
        shortAnswerRow.createCell(0).setCellValue(5); // 题目类型：简答题
        shortAnswerRow.createCell(1).setCellValue("简述Java的垃圾回收机制。"); // 题目内容
        shortAnswerRow.createCell(2).setCellValue(3); // 难度：困难
        shortAnswerRow.createCell(3).setCellValue(20); // 分值
        shortAnswerRow.createCell(4).setCellValue(300); // 时间限制
        shortAnswerRow.createCell(5).setCellValue("Java垃圾回收是一种自动的内存管理机制..."); // 参考答案
        
        // 将工作簿写入字节数组
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        workbook.write(bos);
        workbook.close();
        
        // 创建ByteArrayResource
        return new ByteArrayResource(bos.toByteArray());
    }
} 